/*
 * PublicThread.cpp
 *
 *  Created on: 2017-6-1
 *      Author: root
 */
#ifndef __USE_GNU
#define __USE_GNU
#endif
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include"PublicThread.h"
PublicLock::PublicLock(){
	m_Mutex=(pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
	pthread_mutex_init((pthread_mutex_t*)m_Mutex,NULL);
}
PublicLock::~PublicLock(){
	pthread_mutex_destroy((pthread_mutex_t*)m_Mutex);
	free(m_Mutex);
}
void PublicLock::Lock(){
	pthread_mutex_lock((pthread_mutex_t*)m_Mutex);
}
void PublicLock::UnLock(){
	pthread_mutex_unlock((pthread_mutex_t*)m_Mutex);
}
PublicRWLock::PublicRWLock(){
	m_RwLock=(pthread_rwlock_t*)malloc(sizeof(pthread_rwlock_t));
	pthread_rwlock_init((pthread_rwlock_t*)m_RwLock,NULL);
}
PublicRWLock::~PublicRWLock(){
	pthread_rwlock_destroy((pthread_rwlock_t*)m_RwLock);
	free(m_RwLock);
}
void PublicRWLock::RdLock(){
	pthread_rwlock_rdlock((pthread_rwlock_t*)m_RwLock);
}
void PublicRWLock::WrLock(){
	pthread_rwlock_wrlock((pthread_rwlock_t*)m_RwLock);
}
void PublicRWLock::UnLock(){
	pthread_rwlock_unlock((pthread_rwlock_t*)m_RwLock);
}
int ThreadCreate(pthread_t*id,thrfunc*funfunc,void*args){
    int ret=pthread_create(id,NULL,funfunc,args);
	ThreadBindCPU(*id,-1);
	return ret;
}
int ThreadDestroy(pthread_t id){
    return pthread_join(id,NULL);
}
//glibc低于2.4版本
#if  (__GLIBC__ ==2) && (__GLIBC_MINOR__ < 4 )
#include<sys/syscall.h>
int pthread_setaffinity_np (pthread_t __th, size_t __cpusetsize,const cpu_set_t *__cpuset){
//只有在线程内执行才能绑定	
	return sched_setaffinity(syscall(__NR_gettid), __cpusetsize,__cpuset);
}
#endif
void ThreadBindCPU(pthread_t id,int cpuid){
#ifndef __MINGW32__		
//glibc 2.3没有	
//#if (__GLIBC__ > 2)	|| (__GLIBC__ ==2 && __GLIBC_MINOR__ >3 )
    cpu_set_t cpuset;
	memset(&cpuset,0,sizeof(cpu_set_t));
    static int cpunum=0;
    static int pos=0;
    if(cpunum==0){
        cpunum=sysconf(_SC_NPROCESSORS_ONLN);
    }
    if(cpuid<0){
        cpuid=pos++;
    }
    if(cpunum==0){
        cpuid=0;
    }else{
        cpuid=cpuid%cpunum;
    }
    CPU_ZERO(&cpuset);
    CPU_SET(cpuid,&cpuset);
    pthread_setaffinity_np(id, sizeof(cpu_set_t),&cpuset);
//#endif	
#endif	
}
